/*
 * Copyright (c) 2007, TopCoder, Inc. All rights reserved.
 */

using System;
using System.Windows.Forms;

namespace TopCoder.WinForms.Controls.CalendarView.Views
{
    /// <summary>
    /// <para>
    /// Panel extension that can navigate to a separate view. Used in the views to make active cells.
    /// This is the base class for all panel enhancements in this version.</para>
    /// <para>Basically this panel extension and its concrete extensions will be used by the view implementations
    /// to render specific date entities so they can respond to clicking, which would be requests to change
    /// to a view that is representative of the panel being clicked. When a user clicks on such an entity,
    /// this navigation panel will tell the configured <see cref="CalendarViewControl"/>
    /// to open the configured view on the specified date.</para>
    /// </summary>
    /// <remarks>Thread Safety: This class is immutable and thread safe.</remarks>
    /// <author>Ghostar</author>
    /// <author>yext</author>
    /// <author>argolite</author>
    /// <author>alex.dolin</author>
    /// <version>1.1</version>
    /// <copyright>Copyright (c) 2007, TopCoder, Inc. All rights reserved.</copyright>
    public class NavigationPanel : Panel
    {
        /// <summary>
        /// Represents the parent calendar view.
        /// It is used to move to the destination view when this panel is clicked.
        /// Set in contructor and will not be null or change.
        /// </summary>
        private readonly AbstractCalendarView calendarView;

        /// <summary>
        /// Represents the navigation destination name.
        /// Can be null, indicating that no navoigation is to take place.
        /// Set in the constructor and will never change.
        /// Empty will be set to null.
        /// </summary>
        private readonly string destinationViewName;

        /// <summary>
        /// Represents the date aroound which the destination view will wrap.
        /// Set in the constructor and will not change.
        /// </summary>
        private readonly DateTime dateOfInterest;

        /// <summary>
        /// Creates new instance with the given params, which are just set to the fields.
        /// Set empty <paramref name="destinationViewName"/> to null.
        /// </summary>
        /// <param name="calendarView">The parent calendar view.</param>
        /// <param name="destinationViewName">The destination view's name
        /// for the calendar view control.</param>
        /// <param name="dateOfInterest">The date around which to wrap the destination view.</param>
        /// <exception cref="ArgumentNullException">If <paramref name="calendarView"/> is null.</exception>
        public NavigationPanel(AbstractCalendarView calendarView, string destinationViewName, DateTime dateOfInterest)
        {
            if (calendarView == null)
            {
                throw new ArgumentNullException("calendarView", "Argument calendarView should not be null.");
            }

            this.calendarView = calendarView;
            this.destinationViewName = Helper.GetNullIfEmpty(destinationViewName);
            this.dateOfInterest = dateOfInterest;
        }

        /// <summary>
        /// Raises the <see cref="Control.CreateControl"></see> event.
        /// Sets <see cref="Control.Cursor"/> property to <see cref="Cursors.Hand"/>
        /// if destination view name is not <c>null</c>.
        /// </summary>
        protected override void OnCreateControl()
        {
            base.OnCreateControl();
            if (destinationViewName != null)
            {
                Cursor = Cursors.Hand;
            }
        }

        /// <summary>
        /// Represents the parent calendar view.
        /// It is used to move to the destination view when this panel is clicked.
        /// Set in contructor and will not be null or change.
        /// </summary>
        /// <value>The parent calendar view.</value>
        protected AbstractCalendarView CalendarView
        {
            get
            {
                return calendarView;
            }
        }

        /// <summary>
        /// Called in response to mouse click event.
        /// Activates the destination view using the parent control of the view provided to this panel.
        /// </summary>
        /// <param name="e">The event arguments.</param>
        protected override void OnClick(EventArgs e)
        {
            base.OnClick(e);
            try
            {
                calendarView.Parent.GetView(destinationViewName).DateOfInterest = dateOfInterest;
                calendarView.Parent.CurrentViewType = destinationViewName;
            }
            catch
            {
                // Ignore any thrown exception
            }
        }
    }
}